In [ ]:
import numpy as np
import plotly.graph_objects as go
import plotly.offline
from plotly.subplots import make_subplots
import sympy as sp
from sympy import symbols, exp, sin, cos, pi, I, Heaviside, lambdify, integrate, sqrt
from IPython.display import display, HTML
##Workaround para mostrar fórmulas de LaTeX en Plotly
plotly.offline.init_notebook_mode()
display(HTML(
'<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_SVG"></script>'
))
In [10]:
# 1
# a) Señal discreta
x = np.array([1, 2, 3])
n = np.array([-1, 0, 1])
fig = go.Figure()
fig.add_trace(go.Scatter(x=n, y=x, mode='markers', marker=dict(size=10, color='blue'), name='x[n]'))
for ni, xi in zip(n, x):
fig.add_shape(type="line", x0=ni, y0=0, x1=ni, y1=xi, line=dict(color="blue", width=2))
fig.update_layout(title='Señal discreta', xaxis_title='n', yaxis_title='x[n]', template='plotly_white')
fig.show()
# b) Señal continua simbólica
t = symbols('t')
x_1 = t**2
# Convertir a función para graficar
x_1_func = lambdify(t, x_1, 'numpy')
t_vals = np.linspace(-3, 3, 500)
x_1_vals = x_1_func(t_vals)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t_vals, y=x_1_vals, mode='lines', name='x₁(t) = t²'))
fig.update_layout(title='Señal continua', xaxis_title='$t$', yaxis_title='$x_1(t)$', template='plotly_white')
fig.show()
In [ ]:
# 2
# a) Definir x(t) y y(t)
t = symbols('t', real=True)
x = 3*exp(0.4*t)
y = 2*exp(-0.9*t)
# b) Graficar ambas señales
#$x_func = lambda t: 3 * np.exp(0.4 * t)
x_func = lambdify(t, x, 'numpy')
y_func = lambdify(t, y, 'numpy')
t_vals = np.linspace(-2, 5, 500)
x_vals = x_func(t_vals)
y_vals = y_func(t_vals)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t_vals, y=x_vals, mode='lines', name='$x(t) = 3e^{0.4t}$'))
fig.add_trace(go.Scatter(x=t_vals, y=y_vals, mode='lines', name='$y(t) = 2e^{-0.9t}$'))
fig.update_layout(title='Señales exponenciales', xaxis_title='$t$', yaxis_title='Amplitud', template='plotly_white')
fig.show()
In [ ]:
# 3
# a) Señal continua cos(t)
t = symbols('t', real=True)
y = cos(t)
y_func = lambdify(t, y, 'numpy')
t_vals = np.linspace(0, 10, 500)
y_vals = y_func(t_vals)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t_vals, y=y_vals, mode='lines', name='y(t) = cos(t)'))
fig.update_layout(title='Señal continua: y(t) = cos(t)', xaxis_title='t', yaxis_title='y(t)', template='plotly_white')
fig.show()
# b) Versión discreta cos(n)
n = np.arange(0, 11)
y_1 = np.cos(n)
# c) Stem plot de la señal discreta
fig = go.Figure()
fig.add_trace(go.Scatter(x=n, y=y_1, mode='markers', marker=dict(size=10, color='red'), name='y₁[n] = cos(n)'))
for ni, yi in zip(n, y_1):
fig.add_shape(type="line", x0=ni, y0=0, x1=ni, y1=yi, line=dict(color="red", width=2))
fig.update_layout(title='Señal discreta: y₁[n] = cos(n)', xaxis_title='n', yaxis_title='y₁[n]', template='plotly_white')
fig.show()
In [ ]:
# 4
# a) Definir x(t) = cos(t) + sin(3t)
t = symbols('t', real=True)
x = cos(t) + sin(3*t)
# b) Graficar en [0, 20]
x_func = lambdify(t, x, 'numpy')
t_vals = np.linspace(0, 20, 1000)
x_vals = x_func(t_vals)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t_vals, y=x_vals, mode='lines', name='x(t) = cos(t) + sin(3t)'))
fig.update_layout(title='Suma de señales sinusoidales', xaxis_title='t', yaxis_title='x(t)', template='plotly_white')
fig.show()
In [ ]:
# 5
# a) Definir señal modulada
t = symbols('t', real=True)
x = cos(100*t)*exp(2*t)
# b) Graficar en [0, 2]
x_func = lambdify(t, x, 'numpy')
t_vals = np.linspace(0, 2, 2000)
x_vals = x_func(t_vals)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t_vals, y=x_vals, mode='lines', name='x(t) = cos(100t)·e^(2t)'))
fig.update_layout(title='Modulación de amplitud', xaxis_title='t', yaxis_title='x(t)', template='plotly_white')
fig.show()
In [ ]:
# 6
# a) Definir señal compleja
t = symbols('t', real=True)
y = 2*exp(I*pi*t + I*pi/3)
# b) Extraer partes real e imaginaria
y_real = sp.re(y)
y_imag = sp.im(y)
# c) Graficar ambas partes
y_real_func = lambdify(t, y_real, 'numpy')
y_imag_func = lambdify(t, y_imag, 'numpy')
t_vals = np.linspace(0, 2, 500)
y_real_vals = y_real_func(t_vals)
y_imag_vals = y_imag_func(t_vals)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t_vals, y=y_real_vals, mode='lines', name='Re{y}'))
fig.add_trace(go.Scatter(x=t_vals, y=y_imag_vals, mode='lines', name='Im{y}'))
fig.update_layout(title='Partes real e imaginaria de y(t) = 2e^(jπt + jπ/3)',
xaxis_title='t', yaxis_title='Amplitud', template='plotly_white')
fig.show()
In [ ]:
# 7
# a) Definir función Heaviside
t = symbols('t', real=True)
u = Heaviside(t)
# b) Gráfica continua
u_func = lambdify(t, u, 'numpy')
t_vals = np.linspace(-5, 10, 1000)
u_vals = u_func(t_vals)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t_vals, y=u_vals, mode='lines', name='u(t) - heaviside'))
fig.update_layout(title='Función escalón de Heaviside', xaxis_title='t', yaxis_title='u(t)',
template='plotly_white', yaxis=dict(range=[-0.5, 1.5]))
fig.show()
# c) Valor en t=0
print(f"heaviside(0) = {u.subs(t, 0)}")
# d) Versión discreta con stem
n = np.arange(-5, 11)
u_n = np.array([float(u.subs(t, ni)) for ni in n])
fig = go.Figure()
fig.add_trace(go.Scatter(x=n, y=u_n, mode='markers', marker=dict(size=10, color='blue')))
for ni, ui in zip(n, u_n):
fig.add_shape(type="line", x0=ni, y0=0, x1=ni, y1=ui, line=dict(color="blue", width=2))
fig.update_layout(title='Función Heaviside discreta', xaxis_title='n', yaxis_title='u[n]', template='plotly_white')
fig.show()
In [ ]:
# 8
# a) Definir función rampa
t = symbols('t', real=True)
r = t*Heaviside(t)
# b) Graficar
r_func = lambdify(t, r, 'numpy')
t_vals = np.linspace(-5, 10, 1000)
r_vals = r_func(t_vals)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t_vals, y=r_vals, mode='lines', name='r(t) = t·u(t)'))
fig.update_layout(title='Función rampa', xaxis_title='t', yaxis_title='r(t)', template='plotly_white')
fig.show()
In [ ]:
# 9
# a) Definir pulso rectangular
t = symbols('t', real=True)
T = 2
pT = Heaviside(t + T/2) - Heaviside(t - T/2)
# b) Graficar
pT_func = lambdify(t, pT, 'numpy')
t_vals = np.linspace(-5, 10, 1000)
pT_vals = pT_func(t_vals)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t_vals, y=pT_vals, mode='lines', name=f'p_T(t), T={T}'))
fig.update_layout(title=f'Pulso rectangular (T={T})', xaxis_title='t', yaxis_title='p_T(t)',
template='plotly_white', yaxis=dict(range=[-0.5, 1.5]))
fig.show()
In [ ]:
# 10
# a) Señal original x(t) = t*exp(-t)
t = symbols('t', real=True)
x = t*exp(-t)
x_func = lambdify(t, x, 'numpy')
t_vals = np.linspace(-3, 3, 500)
x_vals = x_func(t_vals)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t_vals, y=x_vals, mode='lines', name='x(t)'))
fig.update_layout(title='Señal original x(t) = te^(-t)', xaxis_title='t', yaxis_title='x(t)',
template='plotly_white', yaxis=dict(range=[-3, 0.5]))
fig.show()
# b) Reflexión: x(-t)
x_reflex = x.subs(t, -t)
x_reflex_func = lambdify(t, x_reflex, 'numpy')
x_reflex_vals = x_reflex_func(t_vals)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t_vals, y=x_reflex_vals, mode='lines', name='x_reflex(t)'))
fig.update_layout(title='Señal reflejada x(-t)', xaxis_title='t', yaxis_title='x_reflex(t)',
template='plotly_white', yaxis=dict(range=[-3, 0.5]))
fig.show()
# c) Traslación: x(t-2)
x_tras = x.subs(t, t-2)
x_tras_func = lambdify(t, x_tras, 'numpy')
x_tras_vals = x_tras_func(t_vals)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t_vals, y=x_tras_vals, mode='lines', name='x_trasladada(t)'))
fig.update_layout(title='Señal trasladada x(t-2)', xaxis_title='t', yaxis_title='x_tras(t)',
template='plotly_white', yaxis=dict(range=[-3, 0.5]))
fig.show()
# d) Ensanchamiento: x(t/3)
x_broad = x.subs(t, t/3)
x_broad_func = lambdify(t, x_broad, 'numpy')
x_broad_vals = x_broad_func(t_vals)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t_vals, y=x_broad_vals, mode='lines', name='x_broad(t)'))
fig.update_layout(title='Señal ensanchada x(t/3)', xaxis_title='t', yaxis_title='x_broad(t)',
template='plotly_white', yaxis=dict(range=[-3, 0.5]))
fig.show()
In [ ]:
# 11
# a) Calcular partes par e impar
t = symbols('t', real=True)
x = t*exp(-t)
x_reflex = x.subs(t, -t)
x_e = (x + x_reflex)/2 # Parte par
x_o = (x - x_reflex)/2 # Parte impar
# b) Graficar las tres señales
x_func = lambdify(t, x, 'numpy')
x_e_func = lambdify(t, x_e, 'numpy')
x_o_func = lambdify(t, x_o, 'numpy')
t_vals = np.linspace(-10, 10, 1000)
x_vals = x_func(t_vals)
x_e_vals = x_e_func(t_vals)
x_o_vals = x_o_func(t_vals)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t_vals, y=x_e_vals, mode='lines', name='x_e(t)'))
fig.add_trace(go.Scatter(x=t_vals, y=x_o_vals, mode='lines', name='x_o(t)'))
fig.add_trace(go.Scatter(x=t_vals, y=x_vals, mode='lines', name='x(t)'))
fig.update_layout(title='Descomposición par e impar', xaxis_title='t', yaxis_title='Amplitud',
template='plotly_white', yaxis=dict(range=[-10, 10]))
fig.show()
# c) Verificar descomposición
verificacion = x_e + x_o
print(f"Verificación x(t) = x_e(t) + x_o(t): {sp.simplify(verificacion - x) == 0}")
In [ ]:
# 12
t = symbols('t', real=True)
T = 2*pi
# Señal
x = sin(t)
# a) Cálculo de energía E
E = integrate(x**2, (t, 0, T))
print(f"Energía E = ∫₀^(2π) sin²(t) dt = {E}")
# b) Cálculo de potencia P
P = E/T
print(f"Potencia P = E/T = {P}")
# c) Cálculo de RMS
RMS = sqrt(P)
print(f"RMS = √P = {RMS}")
# d) Evaluación numérica
var = sp.N(RMS)
print(f"Valor numérico: {var}")